package com.koalacloud.koala.zhaikucloud.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.koalacloud.koala.common.core.util.R;
import com.koalacloud.koala.common.security.annotation.Inner;
import com.koalacloud.koala.zhaikucloud.dto.MallProductDTO;
import com.koalacloud.koala.zhaikucloud.entity.MallProduct;
import com.koalacloud.koala.zhaikucloud.util.EsDataOperation;
import com.koalacloud.koala.zhaikucloud.util.EsIndexOperation;
import com.koalacloud.koala.zhaikucloud.util.EsQueryOperation;
import com.koalacloud.koala.zhaikucloud.service.MallProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;

import java.io.Console;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author: GuoYang
 * @Description ElasticSearch管理
 * @create 2022-04-28
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/es" )
@Tag(name = "ES管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class ElasticSearchController {

    private final EsDataOperation esDataOperation;
    private final EsIndexOperation esIndexOperation;
    private final EsQueryOperation esQueryOperation;

    private final MallProductService mallProductService;


    @Inner(value = false)
    @Operation(summary = "es新增", description = "es新增")
    @PostMapping("/doc")
    public R addDocument() throws Exception {
        MallProduct mallProduct = new MallProduct();
        mallProduct.setTitle("标题");
        mallProduct.setSellPoint("卖点标题");
        mallProduct.setId(UUID.randomUUID().toString());
        mallProduct.setPrice(BigDecimal.valueOf(12.34));
//        mallProduct.setCreateTime(DateTime.now().toLocalDateTime());

        MallProductDTO mallProductDTO = new MallProductDTO();
        BeanUtil.copyProperties(mallProduct, mallProductDTO);

//        ZoneId zoneId = ZoneId.systemDefault();
//        ZonedDateTime zdt = mallProduct.getCreateTime().atZone(zoneId);
//        Date date = Date.from(zdt.toInstant());
//
//        mallProductDTO.setCreateTime(date);

        return R.ok(esDataOperation.insert(mallProductDTO));
    }

    @Inner(value = false)
    @Operation(summary = "批量增加", description = "批量增加")
    @PostMapping("/batchInsert")
    public R batchInsert() throws Exception {
        List<MallProductDTO> list = new ArrayList<>();
        for (int i=1; i<= 20; i++) {
            MallProduct mal = new MallProduct();
            MallProductDTO mallProductDTO = new MallProductDTO();
            mal.setTitle(String.valueOf(i));
            mal.setSellPoint("卖点" + String.valueOf(i));
            mal.setId(UUID.randomUUID().toString());
            mal.setPrice(BigDecimal.valueOf(12.34));
//            mal.setCreateTime(DateTime.now().toLocalDateTime());

            BeanUtil.copyProperties(mal, mallProductDTO);

            list.add(mallProductDTO);
        }

        esDataOperation.batchInsert(list);
        return R.ok();
    }

    @Inner(value = false)
    @Operation(summary = "分页查询Document", description = "分页查询Document")
    @GetMapping("/doc/fromSize")
    public R getFromSize(Page page) throws Exception {
        List<MallProductDTO> list = esQueryOperation.fromSize(MallProductDTO.class, (int)page.getCurrent(), (int)page.getSize());
        return R.ok(list);
    }

    @Inner(value = false)
    @Operation(summary = "searchAfter分页", description = "searchAfter分页")
    @GetMapping("/doc/searchAfter/{sortValue}/{size}")
    public R searchAfter(@PathVariable String sortValue, @PathVariable Integer size) {
        return R.ok(esQueryOperation.searchAfter(MallProductDTO.class, "createTime", sortValue, size));
    }

    @Inner(value = false)
    @Operation(summary = "复杂查询Document", description = "复杂Document")
    @GetMapping("/complex/{id}" )
    public R getBycomplex(@PathVariable("id" ) String id) throws IOException {
        Query query = Query.of(q -> q.match(m -> m.field("age").query(22)));
        List<MallProductDTO> list = esQueryOperation.complexQuery(query, MallProductDTO.class);
        return R.ok(list);
    }

    @Inner(value = false)
    @Operation(summary = "通过id查询Document", description = "通过id查询Document")
    @GetMapping("/doc/{id}" )
    public R getById(@PathVariable("id" ) String id) throws IOException {
        MallProductDTO mallProduct = esDataOperation.getById(id, MallProductDTO.class);
        return R.ok(mallProduct);
    }

    @Inner(value = false)
    @Operation(summary = "通过id删除Document", description = "通过id删除Document")
    @DeleteMapping("/doc/{id}" )
    public R removeById(@PathVariable String id) {
        return R.ok(esDataOperation.delDocId(id, MallProductDTO.class));
    }

    @Inner(value = false)
    @Operation(summary = "通过id修改Document", description = "通过id修改Document")
    @PutMapping
    public R updateById(@PathVariable String id) {
        return R.ok(esDataOperation.upDocId(id, MallProductDTO.class));
    }

    @Inner(value = false)
    @Operation(summary = "查询全部索引", description = "查询全部索引")
    @GetMapping("/indexAll")
    public R getIndexAll() throws IOException {
        return R.ok(esIndexOperation.indexAll());

    }

    @Inner(value = false)
    @Operation(summary = "新增索引", description = "新增索引")
    @GetMapping("/index/{indexName}")
    public R createIndex(@PathVariable String indexName) {
        return R.ok(esIndexOperation.createIndex(indexName));
    }

    @Inner(value = false)
    @Operation(summary = "删除索引", description = "删除索引")
    @DeleteMapping("/index/{indexName}")
    public R deleteIndex(@PathVariable String indexName) {
        return R.ok(esIndexOperation.deleteIndex(indexName));
    }

    @Inner(value = false)
    @Operation(summary = "查询全部数据", description = "查询全部数据")
    @GetMapping("/doc/list")
    public R allList() {
        return R.ok(esDataOperation.queryAllDocument(MallProductDTO.class));
    }

    @Inner(value = false)
    @Operation(summary = "多字段匹配", description = "多字段匹配")
    @GetMapping("/doc/multiMatch/{key}")
    public R multiMatch(@PathVariable String key) {
        return R.ok(esQueryOperation.multiMatch(MallProductDTO.class, key, "sellPoint"));
    }

    @Inner(value = false)
    @Operation(summary = "排序", description = "排序")
    @GetMapping("/doc/OrderQuery/{field}")
    public R OrderQuery(@PathVariable String field) {
        return R.ok(esQueryOperation.OrderQuery(MallProductDTO.class, field, 10));
    }

    @Inner(value = false)
    @Operation(summary = "同步数据到Es", description = "同步数据到Es")
    @PostMapping("/sqltoes")
    public R sqlToEs() throws Exception {

        List<MallProduct> mallProducts = new ArrayList<>();
        List<MallProductDTO> mallProductDTOS = new ArrayList<>();

        mallProducts = mallProductService.list();

        for(MallProduct m : mallProducts) {
            MallProductDTO mallProductDTO = new MallProductDTO();
            BeanUtil.copyProperties(m, mallProductDTO);
            mallProductDTOS.add(mallProductDTO);
        }
        esDataOperation.batchInsert(mallProductDTOS);
        return R.ok();
    }
}
